﻿using System;
using System.Collections.Generic;
using System.Text;

/*
    任务要求：
CEO和CTO开始评定员工一年的工作绩效，员工分为工程师和经理，CTO关注工程师的代码量、经理的新产品数量；CEO关注的是工程师的KPI和经理的KPI以及新产品数量。
由于CEO和CTO对于不同员工的关注点是不一样的，这就需要对不同员工类型进行不同的处理。

 */
namespace Visitor
{

    #region 员工类型
    /// <summary>
    /// 员工基类
    /// </summary>
    public abstract class StaffBase
    {
        protected Random rand = new Random();

        public StaffBase()
        {
            this.KPI = rand.Next(10);
        }
        public int KPI { get; set; }


        public string Name { get; set; }

        public abstract string GetReport(ReportVisitor visitor);
    }

    public class Enginner : StaffBase
    {
        public Enginner()
        {
            this.CodeNumber = rand.Next(1000);
        }
        public int CodeNumber { get; set; }

        public override string GetReport(ReportVisitor visitor)
        {
            return visitor.GetReport(this);
        }
    }

    public class Manager : StaffBase
    {
        public int ProductNewNu { get; set; }
        public Manager()
        {
            this.ProductNewNu = rand.Next(10);
        }

        public override string GetReport(ReportVisitor visitor)
        {
            return visitor.GetReport(this);
        }
    }
    #endregion

    public class ReportForm
    {
        List<StaffBase> staffList = new List<StaffBase>();
        //模拟导入数据
        public ReportForm()
        {
            staffList.Add(new Enginner() { Name = "工程师李" });
            staffList.Add(new Enginner() { Name = "工程师WAng" });
            staffList.Add(new Manager() { Name = "经理黄" });
            staffList.Add(new Manager() { Name = "经理马" });
        }

        public virtual string GetReportByVistor(ReportVisitor visitor)
        {
            StringBuilder sb = new StringBuilder();
            staffList.ForEach(ret =>
            {
                sb.Append(ret.GetReport(visitor));
            });
            return sb.ToString();
        }
    }


    public abstract class ReportVisitor
    {
        public abstract string GetReport(StaffBase staff);
    }

    public class CTOVisitor : ReportVisitor
    {
        public override string GetReport(StaffBase staff)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("姓名:" + staff.Name + "\t");
            if (staff is Enginner)
            {
                Enginner eng = (Enginner)staff;
                sb.Append("职位：工程师\t");
                sb.Append("代码量：" + eng.CodeNumber + "\t");

            }
            else if (staff is Manager)
            {
                Manager manager = (Manager)staff;
                sb.Append("职位：经理\t");
                sb.Append("新产品数量：" + manager.ProductNewNu + "\t");

            }
            sb.Append("\r\n");
            return sb.ToString();
        }
    }
    public class CEOVisitor : ReportVisitor
    {
        public override string GetReport(StaffBase staff)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("姓名:" + staff.Name + "\t");
            sb.Append("KPI：" + staff.KPI + "\t");
            if (staff is Enginner)
            {
                Enginner eng = (Enginner)staff;
                sb.Append("职位：工程师\t");
            }
            else if (staff is Manager)
            {
                Manager manager = (Manager)staff;
                sb.Append("职位：经理\t");
                sb.Append("新产品数量：" + manager.ProductNewNu + "\t");
            }
            sb.Append("\r\n");
            return sb.ToString();
        }
    }
}
